{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "BRUNO DA SILVA 396433 - CK0223\n",
    "\n",
    "# Naive Bayes - Trabalho\n",
    "\n",
    "## Questão 1\n",
    "\n",
    "Implemente um classifacor Naive Bayes para o problema de predizer a qualidade de um carro. Para este fim, utilizaremos um conjunto de dados referente a qualidade de carros, disponível no [UCI](https://archive.ics.uci.edu/ml/datasets/car+evaluation). Este dataset de carros possui as seguintes features e classe:\n",
    "\n",
    "** Attributos\n",
    "1. buying: vhigh, high, med, low\n",
    "2. maint: vhigh, high, med, low\n",
    "3. doors: 2, 3, 4, 5, more\n",
    "4. persons: 2, 4, more\n",
    "5. lug_boot: small, med, big\n",
    "6. safety: low, med, high\n",
    "\n",
    "** Classes\n",
    "1. unacc, acc, good, vgood\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 48,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "from matplotlib import pyplot as plt\n",
    "from sklearn import preprocessing\n",
    "from math import sqrt\n",
    "import pandas as pd\n",
    "import numpy as np\n",
    "import random\n",
    "import math\n",
    "\n",
    " \n",
    "def load_csv(filename):\n",
    "    dataset = cat_to_number(pd.read_csv(filename, header=None))\n",
    "    return np.array(dataset).astype(np.float)\n",
    "\n",
    "#Classes unacc = 1, acc = 2, good = 3, vgood = 4\n",
    "def cat_to_number(dataset):\n",
    "    dic = {'vhigh':4, 'high':3, 'med':2, 'low':1, 'big':3,\n",
    "           'small':1, 'unacc':1, 'acc':2, 'good':3, 'vgood':4,\n",
    "           'more':5, '5more':6}\n",
    "    dataset = dataset.replace(dic)\n",
    "    return dataset\n",
    "    \n",
    "def calculateProbability(x, mean, stdev):\n",
    "    \n",
    "    if stdev == 0:\n",
    "        return 1. if x == mean else .1\n",
    "    \n",
    "    exponent = math.exp(-(math.pow(x-mean,2)/(2*math.pow(stdev,2))))\n",
    "    return (1 / (math.sqrt(2*math.pi) * math.pow(stdev, 2))) * exponent\n",
    "\n",
    "def summarizeByClass(dataset):\n",
    "    separated = separateByClass(dataset)\n",
    "    summaries = {}\n",
    "    for classValue, instances in separated.items():\n",
    "        summaries[classValue] = summarize(instances)\n",
    "    return summaries\n",
    "\n",
    "\n",
    "def summarize(dataset):\n",
    "    summaries = [(mean(attribute), stdev(attribute)) for attribute in zip(*dataset)]\n",
    "    del summaries[-1]\n",
    "    return summaries\n",
    "\n",
    "\n",
    "def mean(numbers):\n",
    "    return sum(numbers)/float(len(numbers))\n",
    " \n",
    "def stdev(numbers):\n",
    "    avg = mean(numbers)\n",
    "    variance = sum([pow(x-avg,2) for x in numbers])/float(len(numbers)-1)\n",
    "    return math.sqrt(variance)\n",
    "\n",
    "def separateByClass(dataset):\n",
    "    separated = {}\n",
    "    for i in range(len(dataset)):\n",
    "        vector = dataset[i]\n",
    "        if (vector[-1] not in separated):\n",
    "            separated[vector[-1]] = []\n",
    "        separated[vector[-1]].append(vector)\n",
    "    return separated\n",
    "\n",
    "def predict(summaries, inputVector):\n",
    "    probabilities = calculateClassProbabilities(summaries, inputVector)\n",
    "    bestLabel, bestProb = None, -1\n",
    "    for classValue, probability in probabilities.items():\n",
    "        if bestLabel is None or probability > bestProb:\n",
    "            bestProb = probability\n",
    "            bestLabel = classValue\n",
    "    return bestLabel\n",
    "\n",
    "def calculateClassProbabilities(summaries, inputVector):\n",
    "    probabilities = {}\n",
    "    for classValue, classSummaries in summaries.items():\n",
    "        probabilities[classValue] = 1\n",
    "        for i in range(len(classSummaries)):\n",
    "            mean, stdev = classSummaries[i]\n",
    "            x = inputVector[i]\n",
    "            probabilities[classValue] *= calculateProbability(x, mean, stdev)\n",
    "    return probabilities\n",
    "\n",
    "def getPredictions(summaries, testSet):\n",
    "    predictions = []\n",
    "    for i in range(len(testSet)):\n",
    "        result = predict(summaries, testSet[i])\n",
    "        predictions.append(result)\n",
    "    return predictions\n",
    "\n",
    "def getAccuracy(testSet, predictions):\n",
    "    correct = 0\n",
    "    for i in range(len(testSet)):\n",
    "        if testSet[i][-1] == predictions[i]:\n",
    "            correct += 1\n",
    "    return (correct/float(len(testSet))) * 100.0"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 54,
   "metadata": {},
   "outputs": [],
   "source": [
    "filename = 'carData.csv'\n",
    "ds = load_csv(filename)\n",
    "ds_train, ds_test = train_test_split(ds, test_size = 0.4)\n",
    "pred = getPredictions(summarizeByClass(ds), ds_test)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 50,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "69.50867052023122"
      ]
     },
     "execution_count": 50,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "getAccuracy(ds_test, pred)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Questão 2\n",
    "Crie uma versão de sua implementação usando as funções disponíveis na biblioteca SciKitLearn para o Naive Bayes ([veja aqui](http://scikit-learn.org/stable/modules/naive_bayes.html)) "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 51,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "GaussianNB(priors=None)"
      ]
     },
     "execution_count": 51,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "from sklearn.naive_bayes import GaussianNB\n",
    "\n",
    "Y_train = ds_train[:,6]\n",
    "Y_test = ds_test[:,6]\n",
    "\n",
    "X_train = ds_train[:,0:6]\n",
    "X_test = ds_test[:,0:6]\n",
    "\n",
    "clf.fit(X_train, Y_train)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 52,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "array([ 1.,  4.,  1.,  1.,  4.,  1.,  3.,  1.,  1.,  1.,  3.,  1.,  1.,\n",
       "        1.,  1.,  4.,  4.,  1.,  1.,  1.,  1.,  1.,  2.,  4.,  2.,  1.,\n",
       "        1.,  1.,  4.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  4.,  3.,\n",
       "        4.,  1.,  4.,  4.,  1.,  1.,  1.,  1.,  4.,  1.,  1.,  1.,  1.,\n",
       "        1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  2.,  1.,  1.,  3.,  2.,\n",
       "        1.,  1.,  1.,  1.,  1.,  1.,  4.,  1.,  1.,  2.,  1.,  4.,  1.,\n",
       "        1.,  4.,  1.,  1.,  4.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,\n",
       "        1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,\n",
       "        1.,  1.,  1.,  4.,  1.,  1.,  1.,  1.,  1.,  2.,  1.,  1.,  1.,\n",
       "        1.,  4.,  1.,  1.,  1.,  1.,  1.,  4.,  1.,  1.,  1.,  1.,  1.,\n",
       "        3.,  1.,  1.,  1.,  4.,  1.,  1.,  1.,  4.,  1.,  1.,  4.,  2.,\n",
       "        1.,  2.,  1.,  1.,  1.,  4.,  2.,  1.,  2.,  1.,  3.,  1.,  1.,\n",
       "        1.,  2.,  1.,  4.,  2.,  4.,  4.,  1.,  4.,  2.,  1.,  1.,  4.,\n",
       "        4.,  1.,  1.,  4.,  2.,  2.,  1.,  4.,  1.,  4.,  1.,  1.,  1.,\n",
       "        4.,  1.,  1.,  2.,  1.,  4.,  4.,  1.,  1.,  4.,  4.,  4.,  4.,\n",
       "        4.,  1.,  2.,  1.,  1.,  2.,  1.,  4.,  1.,  2.,  4.,  1.,  1.,\n",
       "        1.,  3.,  1.,  2.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  2.,  2.,\n",
       "        1.,  2.,  4.,  1.,  1.,  4.,  1.,  4.,  2.,  4.,  1.,  1.,  1.,\n",
       "        2.,  4.,  1.,  1.,  1.,  3.,  1.,  1.,  1.,  1.,  1.,  2.,  1.,\n",
       "        1.,  1.,  3.,  2.,  1.,  1.,  1.,  1.,  1.,  2.,  1.,  1.,  4.,\n",
       "        1.,  1.,  1.,  1.,  1.,  4.,  1.,  1.,  4.,  1.,  4.,  1.,  1.,\n",
       "        1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  4.,  1.,\n",
       "        1.,  2.,  2.,  1.,  1.,  1.,  1.,  3.,  1.,  4.,  1.,  1.,  4.,\n",
       "        1.,  1.,  1.,  1.,  1.,  2.,  1.,  1.,  1.,  2.,  1.,  1.,  2.,\n",
       "        1.,  1.,  1.,  4.,  1.,  1.,  4.,  4.,  2.,  1.,  4.,  1.,  1.,\n",
       "        1.,  1.,  1.,  1.,  4.,  1.,  4.,  1.,  4.,  4.,  1.,  1.,  1.,\n",
       "        1.,  3.,  1.,  1.,  4.,  1.,  2.,  1.,  1.,  4.,  4.,  1.,  2.,\n",
       "        4.,  1.,  2.,  1.,  1.,  2.,  1.,  4.,  1.,  4.,  1.,  1.,  1.,\n",
       "        1.,  4.,  1.,  1.,  4.,  2.,  1.,  1.,  1.,  1.,  4.,  2.,  2.,\n",
       "        2.,  1.,  1.,  1.,  1.,  4.,  2.,  1.,  1.,  1.,  1.,  4.,  1.,\n",
       "        1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  4.,  1.,  1.,  1.,\n",
       "        4.,  2.,  1.,  1.,  1.,  2.,  1.,  1.,  1.,  1.,  4.,  1.,  2.,\n",
       "        1.,  1.,  1.,  2.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  4.,  1.,\n",
       "        1.,  1.,  4.,  4.,  4.,  1.,  1.,  1.,  1.,  1.,  1.,  2.,  1.,\n",
       "        1.,  1.,  4.,  1.,  1.,  1.,  1.,  1.,  4.,  4.,  2.,  1.,  1.,\n",
       "        4.,  4.,  1.,  1.,  1.,  1.,  1.,  4.,  1.,  1.,  1.,  1.,  1.,\n",
       "        4.,  4.,  2.,  1.,  1.,  4.,  4.,  1.,  1.,  1.,  1.,  1.,  1.,\n",
       "        1.,  1.,  1.,  4.,  4.,  1.,  4.,  1.,  4.,  1.,  1.,  1.,  1.,\n",
       "        1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,\n",
       "        1.,  1.,  4.,  4.,  1.,  1.,  1.,  1.,  1.,  1.,  2.,  1.,  1.,\n",
       "        4.,  1.,  1.,  1.,  1.,  4.,  2.,  1.,  4.,  4.,  1.,  1.,  1.,\n",
       "        1.,  1.,  1.,  1.,  1.,  1.,  1.,  2.,  1.,  4.,  2.,  4.,  1.,\n",
       "        1.,  4.,  1.,  4.,  1.,  1.,  1.,  1.,  2.,  2.,  2.,  1.,  1.,\n",
       "        1.,  4.,  1.,  1.,  4.,  1.,  1.,  1.,  1.,  1.,  4.,  1.,  1.,\n",
       "        4.,  1.,  4.,  4.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  2.,\n",
       "        1.,  2.,  2.,  4.,  1.,  1.,  1.,  1.,  1.,  2.,  1.,  1.,  1.,\n",
       "        1.,  4.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  2.,  1.,  1.,  1.,\n",
       "        1.,  1.,  1.,  1.,  1.,  1.,  4.,  1.,  1.,  2.,  1.,  1.,  1.,\n",
       "        2.,  4.,  1.,  1.,  1.,  4.,  4.,  1.,  1.,  1.,  1.,  1.,  1.,\n",
       "        1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  2.,  4.,  1.,  1.,\n",
       "        4.,  1.,  1.,  1.,  4.,  1.,  1.,  1.,  4.,  4.,  1.,  2.,  1.,\n",
       "        1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  2.,  1.,  1.,  1.,  1.,\n",
       "        1.,  1.,  1.,  4.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  1.,  4.,\n",
       "        1.,  2.,  1.])"
      ]
     },
     "execution_count": 52,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pred = clf.predict(X_test)\n",
    "pred"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 53,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "74.42196531791907"
      ]
     },
     "execution_count": 53,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "getAccuracy(ds_test, pred)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
